# _*_ coding:utf-8 _*_
# 开发团队: Mavericks
# 开发人员：Maverick·Ming
# 开发IDE： PyCharm
#   项目名：HelloWorld
#   文件名：6.13 类属性和类方法.py
# 开发时间：2021/3/26 22:45

class A(object):

    # 类属性，直接类里定义的变量
    # 类属性可以通过类或者类的实例访问到
    # 类属性只能通过类对象修改，无法通过实例对象修改
    # 实例调用修改的只是实例对象的属性
    count = 0

    def __init__(self):
        self.name = 'MaverickMing'
        # self代表当前实例对象
        # 实例属性，通过实例对象添加的属性属于实例属性
        # 实例属性，只能通过实例对象来访问和修改，类对象无法访问


a = A()
a.count = 10  # 给实力属性赋值
print(A.count)  # 类属性 count = 0
print(a.count)  # 实例属性 count = 10
print(a.name)  # name是实例属性，只能通过实例对象来访问和修改
# print(A.name)  # 类对象无法访问实例对象的属性name

# 类属性和实例属性分别在什么情况下使用呢
# 属性是公有的，公开的情况下，用类属性name
# 属性是私有的，加密的情况下，用实例属性_name


class B(object):

    # 实例方法
    # 在类定义中，以self作为第一个参数传参的方法
    # 实例方法在调用时，Python会将调用对象作为self传入
    def test(self):
        print('这是实例self方法', self)

    # 类方法
    # 在内部使用#classmethod修饰的方法属于类方法
    # 第一个参数是cls(class简写，因为class是类的关键字，所以要用简写)
    # 也会被自动传递，cls是当前类对象
    @classmethod
    def test2(cls):
        print('这是类cls方法', cls)

    # 静态方法
    # 在类中使用@staticmethod 修饰的方法属于静态方法
    # 一个与当前类无关的方法，就如同类外部的函数
    # 一般用来做工具方法，
    @staticmethod
    def test3():
        print('这是不需要指定参数的静态方法！')


b = B()
# 实例方法可以通过实例、类调用
# 当通过实例调用时，会自动将当前对象当作self传入
b.test()
# 当通过类调用时，不会自动将当前类self传入,此时需要手动传self
B.test(a)
# b.lesson练习() == B.lesson练习(a)

# 类方法与实例方法的区别，实例方法第一个参数是self，类方法第一个参数是cls
# 类方法可以通过类、实例调用，没有区别
b.test2()
B.test2()
# b.test2() == B.test2()

# 静态方法
# 静态方法不需要指定任何的默认参数，可以通过类、实例调用
b.test3()
B.test3()
# b.test3() == B.test3()

